package test.thread.lock ;

import java.util.concurrent.locks.Condition ;
import java.util.concurrent.locks.Lock ;
import java.util.concurrent.locks.ReentrantLock ;

/**
 * 交替输出 many_many
 * @author 80002165 @date 2017年5月4日 下午9:33:11
 */
public class P_C_ThreadLock_M_M {
    static class Service {
        private Lock lock = new ReentrantLock() ;
        private boolean isFirst = true ;
        private Condition print0Condition = lock.newCondition() ;
        private Condition print1Condition = lock.newCondition() ;
        private Condition condition = lock.newCondition() ;
        
        public void print0() {
            try {
                lock.lock() ;
                while (isFirst) {
                    condition.await() ;
                }
                System.out.println(Thread.currentThread().getName() + ",11111") ;
                isFirst = true ;
                condition.signalAll() ;
            } catch (Exception e) {
                e.printStackTrace() ;
            } finally {
                lock.unlock() ;
            }
        }
        
        public void print1() {
            try {
                lock.lock() ;
                while (!isFirst) {
                    condition.await() ;
                }
                System.out.println(Thread.currentThread().getName() + ",00000") ;
                isFirst = false ;
                condition.signalAll() ;
            } catch (Exception e) {
                e.printStackTrace() ;
            } finally {
                lock.unlock() ;
            }
        }
    }
    
    static class Thread0 extends Thread {
        Service service ;
        
        public Thread0(Service service, String name) {
            super(name) ;
            this.service = service ;
        }
        
        @Override
        public void run() {
            while (true) {
                service.print0() ;
            }
        }
    }
    
    static class Thread1 extends Thread {
        Service service ;
        
        public Thread1(Service service, String name) {
            super(name) ;
            this.service = service ;
        }
        
        @Override
        public void run() {
            while (true) {
                service.print1() ;
            }
        }
    }
    
    public static void main(String[] args) {
        Service service = new Service() ;
        for (int i = 0; i < 5; i++) {
            Thread thread1 = new Thread1(service, "printL" + (i + 1)) ;
            Thread thread0 = new Thread0(service, "printQ" + (i + 1)) ;
            thread1.start() ;
            thread0.start() ;
        }
    }
}
